/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                       
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: eeprom_polled.c$
* $Version : 3.6.3.0$
* $Date    : Jun-4-2010$
*
* Comments:
*
*   This file contains read/write functions for the Microchip 24LC16 EEPROMs
*   using I2C polled driver.
*
*END************************************************************************/


#include <mqx.h>
#include <bsp.h>
#include "I2Cmemory.h"


/*FUNCTION****************************************************************
* 
* Function Name    : i2c_write_eeprom_polled
* Returned Value   : void
* Comments         : 
*   Writes the provided data buffer at address in I2C EEPROMS
*
*END*********************************************************************/

void I2C_Write_Polled
(
	/* [IN] The file pointer for the I2C channel */
	MQX_FILE_PTR fd,

	/* [IN] The address in EEPROM to write to */
	uint_32    addr,
	
	/* [IN] The array of characters are to be written in EEPROM */
	uchar_ptr  buffer,
	
	/* [IN] Number of bytes in that buffer */
	uint_32    n,
	
	uint_8 chipaddr
)
{ /* Body */

	uint_32       length;
	uint_32       param;
	uint_32       result;
	uint_8        mem;
	
	do
	{
		/* I2C bus address also contains memory block index */
		param = chipaddr | ((addr >> 8) & 7);
		ioctl (fd, IO_IOCTL_I2C_SET_DESTINATION_ADDRESS, &param);
		length = n;
		
		/* Initiate start and send I2C bus address */
		fwrite (&mem, 1, 0, fd);

		/* Check ack (device exists) */
		if (I2C_OK == ioctl (fd, IO_IOCTL_FLUSH_OUTPUT, &param))
		{
			if (param) 
			{
				/* Stop I2C transfer */
				break;
			}
		}
		/* Write address within memory block */
		mem = addr & 0xFF;
		result = fwrite (&mem, 1, 1, fd);
		result = fwrite (buffer, 1, length, fd);
		result = fflush (fd);
		
		/* Stop I2C transfer - initiate EEPROM write cycle */
		ioctl (fd, IO_IOCTL_I2C_STOP, NULL);

		/* Wait for EEPROM write cycle finish - acknowledge */
		result = 0;
		do 
		{  
			/* Sends just I2C bus address, returns acknowledge bit and stops */
			fwrite (&result, 1, 0, fd); 
			ioctl (fd, IO_IOCTL_FLUSH_OUTPUT, &param);
			ioctl (fd, IO_IOCTL_I2C_STOP, NULL);
			result++;
		} while (param & 1);

      /* Next round */
      buffer += length;
      addr += length;
      n -= length;
        
   } while (n);
} /* Endbody */

   
/*FUNCTION****************************************************************
* 
* Function Name    : i2c_read_eeprom_polled
* Returned Value   : void
* Comments         : 
*   Reads into the provided data buffer from address in I2C EEPROM
*
*END*********************************************************************/

void I2C_Read_Polled
(
	/* [IN] The file pointer for the I2C channel */
	MQX_FILE_PTR fd,
	
	/* [IN] The address in EEPROM to read from */
	uint_32    addr,
	
	/* [IN] The array of characters to be written into */
	uchar_ptr  buffer,
	
	/* [IN] Number of bytes to read */
	uint_32    n,
	
	uint_8 chipaddr
)
{ /* Body */
	uint_32       param;
	uint_32       result;
	uint_8        mem;
	
	if (0 == n) 
	{
		return;
	}

	/* I2C bus address also contains memory block index */
	param = chipaddr | ((addr >> 8) & 7);
	ioctl (fd, IO_IOCTL_I2C_SET_DESTINATION_ADDRESS, &param);
	/* Initiate start and send I2C bus address */
	fwrite (&mem, 1, 0, fd);

	/* Check ack (device exists) */
	if (I2C_OK == ioctl (fd, IO_IOCTL_FLUSH_OUTPUT, &param))
	{
		if (param) 
		{
			/* Stop I2C transfer */
			ioctl (fd, IO_IOCTL_I2C_STOP, NULL);
			return;
		}
	}
	/* Write address within memory block */
	mem = addr & 0xFF;
	result = fwrite (&mem, 1, 1, fd);

	/* Wait for completion */
	result = fflush (fd);
	
	/* Restart I2C transfer for reading */
	ioctl (fd, IO_IOCTL_I2C_REPEATED_START, NULL);
	
	/* Set read request */
	param = n;
	ioctl (fd, IO_IOCTL_I2C_SET_RX_REQUEST, &param);
	
	/* Read all data */
	result = fread (buffer, 1, n, fd);
	
	/* Wait for completion */
	result = fflush (fd);
	/* Stop I2C transfer - initiate EEPROM write cycle */
	ioctl (fd, IO_IOCTL_I2C_STOP, NULL);
} /* Endbody */
      
